package com.bocai.test;

import net.sf.json.JSONObject;

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;

public class hello {

    public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
    public static final String privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMSqoQDi4r0ot9wW" +
            "92W5EqHp+x0ytdIUkdU3lsOIWZ905X99FbhNb3GvE3UC2M7wNpvFAE0P3Jy3m8vD" +
            "RqYaOKUbaqqQ0G1TAjZN6zUoFdGF4HnTv2n/0FYuHUgyCXEoBk6bMrjtD1epdOum" +
            "pg7Q5mjSoEoZsxfA2Y6ZbyOm0hNTAgMBAAECgYEAvMJgoe8iXRgV0EKi1Zmazpk7" +
            "Ej030hk4F4OxSp82FhwmogS2shxwmJbHgAlpesWIRF4C+fP9dNWtzRbyWj7UmcPZ" +
            "QxOPuRRk3qgmuUc8LfjSnHYx5FixalLEMxR4WdvYrmxJvYgzc286u3Zv/VXsIHLS" +
            "9x1qwTXJf/TeaIBBwHECQQDziAztYlAivENnF6WXxJNxAhnaKhQQkkSIilR2IFVs" +
            "9J/rH9GsRwvfPt1g6Q7gwEkI1R3hUihD7MJDKnz+QhVtAkEAzrxSt75RyVboVyPH" +
            "gfgoRXXANOlqgER6lRS7MX11zaIm37TVjLBRcbVGjaVpeAz2iFyFy6RDm+jkZ4fn" +
            "QIETvwJBAKJpmo16Io131s/bMmGMBPS5/PnFVEpU8gXJk1iQachXQIuzVcc6Po2t" +
            "REDMTVLQiiSs1NefTiE2tbvLiz6aXeUCQAlT6/OIbc5E0pTj82OE2+RObM62XWzO" +
            "Ki3B0rRn8cHGeDSNxzji17nmsPlBJmIZS6JZclv+3GITfwLA2glKCacCQHOF2OEe" +
            "HYGiljbN57qmHtTd4Rw3pBOdGpwTomT+jffTspCuFFfZb57YHNf2R7S64r2FnP7C" +
            "cjyYJumBFxzBudM=";

    public static final String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEqqEA4uK9KLfcFvdluRKh6fsd" +
            "MrXSFJHVN5bDiFmfdOV/fRW4TW9xrxN1AtjO8DabxQBND9yct5vLw0amGjilG2qq" +
            "kNBtUwI2Tes1KBXRheB5079p/9BWLh1IMglxKAZOmzK47Q9XqXTrpqYO0OZo0qBK" +
            "GbMXwNmOmW8jptITUwIDAQAB";

    public static void main(String[] args) {

        Map params = new HashMap();

        params.put("requestId", UUID.randomUUID().toString());
        params.put("vendorId", "FM");
        params.put("appId", "FMBALL");
        params.put("timestamp", System.currentTimeMillis() + "");
        Map<String, String> business = new HashMap<>();

        business.put("sportId", "1");
        business.put("language", "6");
        String businessParamStr = JSONObject.fromObject(business).toString();
        params.put("businessParam", businessParamStr);
//        params.put("businessParam", "{\"sportId\":\"1\",\"language\":\"6\"}");

        String content = getSignContent(params);

        String sign = sign(content, privateKey, "utf-8");
        params.put("sign", sign);

        String paramsString = JSONObject.fromObject(params).toString();
        System.out.println("paramsString=" + paramsString);

        System.out.println("verify=" + verify(content, sign, publicKey, "utf-8"));

//        String str = HttpUtils.sendPost("https://dev.tcmapi.cn/v1.1/book/country/list ", paramsString);
        String str = httputils.submitPostData("https://dev.tcmapi.cn/v1.1/book/country/list ", params, "utf-8");

        System.out.println("str=" + str);

    }

    /**
     * @param sortedParams
     * @return
     */
    public static String getSignContent(Map<String, String> sortedParams) {
        StringBuffer content = new StringBuffer();
        List<String> keys = new ArrayList<String>(sortedParams.keySet());
        Collections.sort(keys);
        int index = 0;
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = sortedParams.get(key);
            if (areNotEmpty(key, value)) {
                content.append((index == 0 ? "" : "&") + key + "=" + value);
                index++;
            }
        }
        return content.toString();
    }

    /**
     * RSAǩ��
     *
     * @param content       ��ǩ������
     * @param privateKey    �̻�˽Կ
     * @param input_charset �����ʽ
     * @return ǩ��ֵ
     */
    public static String sign(String content, String privateKey, String input_charset) {
        try {
            byte[] decode = Base64.getDecoder().decode(privateKey);
            PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(decode);
            KeyFactory keyf = KeyFactory.getInstance("RSA");
            PrivateKey priKey = keyf.generatePrivate(priPKCS8);
            Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
            signature.initSign(priKey);
            signature.update(content.getBytes(input_charset));
            byte[] signed = signature.sign();
            return Base64.getEncoder().encodeToString(signed);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * RSA��ǩ�����
     *
     * @param content       ��ǩ������
     * @param sign          ǩ��ֵ
     * @param public_key    ��Կ
     * @param input_charset �����ʽ
     * @return ����ֵ
     */
    public static boolean verify(String content, String sign, String public_key, String input_charset) {
        try {
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            byte[] encodedKey = Base64.getDecoder().decode(public_key);
            PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
            java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);

            signature.initVerify(pubKey);
            signature.update(content.getBytes(input_charset));

            boolean bverify = signature.verify(Base64.getDecoder().decode(sign));
            return bverify;

        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    /**
     * ���ָ�����ַ����Ƿ�Ϊ�ա�
     * <ul>
     * <li>SysUtils.isEmpty(null) = true</li>
     * <li>SysUtils.isEmpty("") = true</li>
     * <li>SysUtils.isEmpty("   ") = true</li>
     * <li>SysUtils.isEmpty("abc") = false</li>
     * </ul>
     *
     * @param value �������ַ���
     * @return true/false
     */
    private static boolean isEmpty(String value) {
        int strLen;
        if (value == null || (strLen = value.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if ((Character.isWhitespace(value.charAt(i)) == false)) {
                return false;
            }
        }
        return true;
    }

    private static boolean areNotEmpty(String... values) {
        boolean result = true;
        if (values == null || values.length == 0) {
            result = false;
        } else {
            for (String value : values) {
                result &= !isEmpty(value);
            }
        }
        return result;
    }
}
